package com.oneguy;

import com.alibaba.fastjson.JSON;
import db.RoomInfoEntity;
import org.hibernate.*;
import org.hibernate.cfg.Configuration;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.*;

/**
 * Created by ZuoShu on 16/12/2.
 */
public class Fisher implements Runnable {
    private SessionFactory sessionFactory;

    private boolean stop;

    public Fisher() {
        readConfig();
        initHibernate();
        readRooms();
    }

    public static void main(final String[] args) throws Exception {
        Fisher main = new Fisher();
//        List<RoomInfoEntity> rooms = main.readRooms();
//        System.out.println(rooms.toString());
        main.runInThread();
    }

    private void readConfig() {
        Properties p = new Properties();
        try {
            String filePath = "./config.xml";
            p.loadFromXML(new FileInputStream(filePath));
            Config.setDb(p.getProperty("db"));
            Config.setRemote(p.getProperty("remote"));
            Config.setInternal(Integer.valueOf(p.getProperty("internal")));
        } catch (InvalidPropertiesFormatException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void initHibernate() {
        Configuration configuration = new Configuration();
        configuration.configure();
        configuration.setProperty("hibernate.connection.url", Config.getDb());
        sessionFactory = configuration.buildSessionFactory();
    }

    private List<RoomInfoEntity> readRooms() {
        Session session = null;
        List<RoomInfoEntity> result = new ArrayList<>();
        try {
            session = sessionFactory.openSession();

            List<RoomInfoEntity> roomInfoEntityList = session.createQuery("from RoomInfoEntity").list();

            for (Iterator iterator = roomInfoEntityList.iterator(); iterator.hasNext(); ) {
                RoomInfoEntity room = (RoomInfoEntity) iterator.next();
                result.add(room);
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (session != null) {
                session.close();
            }
        }
        return result;
    }

    private void runInThread() {
        Thread thread = new Thread(this);
        thread.run();
    }

    @Override
    public void run() {
        while (!stop) {
            List<RoomInfoEntity> rooms = readRooms();
            List<RoomInfoEntity> newRooms = report(rooms);
            update(newRooms);
            try {
                Thread.sleep(Config.getInternal());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }

    private List<RoomInfoEntity> report(List<RoomInfoEntity> rooms) {
        String roomString = JSON.toJSONString(rooms);
        String result = sendPost(Config.getRemote(), roomString);
        return JSON.parseArray(result, RoomInfoEntity.class);
    }

    private void update(List<RoomInfoEntity> rooms) {
        if (rooms != null && rooms.size() > 0) {
            for (RoomInfoEntity room : rooms) {
                update(room);
            }
        }

    }

    private void update(RoomInfoEntity room) {
        if (room == null) {
            return;
        }
        Session session = null;
        try {
            session = sessionFactory.openSession();
            String sql = "update roominfo set factor = " + room.getFactor() + " where firsttableguid = " + room.getFirstTableGuid() + " and roomguid=" + room.getRoomGuid();
            Transaction transaction = session.beginTransaction();
            SQLQuery sqlQuery = session.createSQLQuery(sql);
            int result = sqlQuery.executeUpdate();
            System.out.println("update room id:" + room.getRoomGuid() + " start:"
                    + room.getFirstTableGuid() + " end:" + room.getEndTableGuid() + "->" + room.getFactor() + " result:+" + result);
            transaction.commit();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (session != null) {
                session.close();
            }
        }
    }

    public String sendPost(String url, String param) {
        PrintWriter out = null;
        BufferedReader in = null;
        String result = "";
        HttpURLConnection conn = null;
        try {
            URL realUrl = new URL(url);
            // 打开和URL之间的连接
            conn = (HttpURLConnection) realUrl.openConnection();
            // 设置通用的请求属性
            conn.setRequestProperty("content-type", "application/json;charset=UTF-8");
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // 获取URLConnection对象对应的输出流
            out = new PrintWriter(conn.getOutputStream());
            // 发送请求参数
            out.print(param);
            // flush输出流的缓冲
            out.flush();
            // 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(
                    new InputStreamReader(conn.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            System.out.println("发送 POST 请求出现异常！" + e);
            e.printStackTrace();
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
                if (conn != null) {
                    conn.disconnect();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return result;
    }
}